package com.example.gokchinesefoodmapmcdev.filter;

import com.example.gokchinesefoodmapmcdev.dao.SysMenuDAO;
import com.example.gokchinesefoodmapmcdev.dao.SysRoleDAO;
import com.example.gokchinesefoodmapmcdev.entity.sys.SysMenu;
import com.example.gokchinesefoodmapmcdev.entity.sys.SysRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;

/**
 * 自定义权限验证规则
 * 实现FilterInvocationSecurityMetadataSource接口，重写getAttributes，将原本的规则覆盖
 */
@Component
public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    /**
     * 角色前缀名
     */
    private final static String ROLE_PREFIX = "ROLE_";

    @Autowired
    private SysRoleDAO sysRoleDAO;

    @Autowired
    private SysMenuDAO sysMenuDAO;

    // 路径匹配工具类
    private AntPathMatcher antPathMatcher = new AntPathMatcher();


    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        // 获取request对象
        HttpServletRequest request = ((FilterInvocation) object).getRequest();

        // 1. 获取用户请求
        String requestURI = request.getRequestURI();

        // 2. 获取权限表中所有的路径
        List<SysMenu> sysMenus = sysMenuDAO.selectList(null);

        // 3. 判断路径中是否包含当前请求路径
        boolean flag = true;
        for (SysMenu sysMenu : sysMenus) {
            if(sysMenu.getUrl() == null || sysMenu.getUrl() == ""){
                continue;
            }

            // 4. 如果匹配上，则依据路径，找到该请求地址的可访问的角色集合
            if (antPathMatcher.match(sysMenu.getUrl(), requestURI)) {
                flag = false;
                List<SysRole> roles = sysRoleDAO.selectSysRolesByMenuId(sysMenu.getMenuId());
                // 5. 将得到的角色名字的集合放入SecurityConfig中的一个List集合中，Spring Security会自行匹配
                String[] roleNames = new String[roles.size()];
                for (int i = 0; i < roleNames.length; i++) {
                    roleNames[i] = ROLE_PREFIX + roles.get(i).getRoleName();
                }
                return SecurityConfig.createList(roleNames);
            }
        }
        if(flag){
            return SecurityConfig.createList(ROLE_PREFIX + "普通用户");
        }
        return SecurityConfig.createList();
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}
